serverless-v1.0.0-rc.1を試してみた(2) – 実際にデプロイしてみる
モバイルアプリサービス部の五十嵐です。
前回は基本的なコマンドを試してみました。今回は実際に作成したLambdaをデプロイするまでを書いていきます。serverlessプロジェクトでの成果物は こちら にあります。
環境
- serverless 1.0.0-rc.1
- node.js 4.3.2
- npm 2.14.12
npmのインストール
serverless v1.0.0-rcにはLambdaが参照できる環境変数を設定する機能がまだ無いので、configというnpmを使いました。configは、設定ファイルのJSONを外出しして簡単に読み込めるライブラリです。
npm init
コマンドで package.json を作った後に、 npm install <パッケージ名> --save
コマンドを実行します。package.json の dependencies に書き込みたいので --save
オプションを付けますnpmはデプロイパッケージに含めるので必ずローカルにインストールします。
# npm init --yes # npm install config --save npm WARN package.json sample@1.0.0 No description npm WARN package.json sample@1.0.0 No repository field. npm WARN package.json sample@1.0.0 No README data config@1.21.0 node_modules/config └── json5@0.4.0
以下はconfigの設定ファイルの設定例です。本物の設定ファイルにはKMSのトークンなどが書かれているため、GitHubに登録されないよう.gitignoreに追加しておきます。また合わせてnode_modulesディレクトリも.gitignoreに追加しておきます。
# ll config total 16 -rw-r--r-- 1 bisque33 staff 333B 9 10 07:15 default.json # <-こっちが本物 -rw-r--r-- 1 bisque33 staff 139B 9 10 07:17 default_sample.json # config/default_sample.json { "kmsEncryptedToken": "<kmsEncryptedToken>", "invokeFunctionARN": "arn:aws:lambda:<region>:<accountId>:function:<functionName>" } # echo config/default.json >> .gitignore # echo node_modules >> .gitignore
IAMの設定
IAMの設定を行います。このLambdaが必要とするAWSの権限は以下の2つです。
- 他のLambdaをInvokeする。
- KMSに暗号化してあるSlackのアクセストークンを取得する。
serverlessの設定ファイルに以下のように記述することで、必要な権限を持ったIAMが作成されます。書き方はIAMのJSONをほぼそのままYAMLにしたような形式です。
provider: ... # you can add statements to the Lambda function's IAM Role here iamRoleStatements: - Effect: "Allow" Action: - "lambda:InvokeFunction" Resource: "arn:aws:lambda:ap-northeast-1:*:function:*" - Effect: "Allow" Action: - "kms:Decrypt" Resource: "*"
Lambdaの設定
Lambda自体の設定は、serverlessの設定ファイルのfunctions以下に記述します。今回作成するLambdaは1つですが、複数のLambdaの設定を書くことも可能です。slashCommandsがLambdaの名前、handlerエントリーポイントの関数名です。トリガーを設定しないのであればここまでで良いです。
eventsはトリガーの設定です。今回はAPI Gatewayから呼び出されるようにしたいので、http以下の属性を書いていきます。書き方は serverless/01-apigateway.md を参照します。
functions: slashCommands: handler: handler.slashCommands events: - http: path: slack/slash-commands method: post request: template: application/x-www-form-urlencoded: '{ "body": $input.json("$") }' passThrough: NEVER
API Gatewayのリソースを設定する方法も一応載っているのですが、深みに嵌りそうなので今回は手動で作成しました。
Lambdaの実装
serverlessでプロジェクトを作成すると handler.js というファイルが作成されます。その中にエントリーポイントとなる関数が用意されていますので、その中に実際の処理を書いていきます。実装コードの module.exports.XXX
と先ほどの設定に書いたLambdaの設定の functions:<functionの名前>:handler:<ファイル名>.XXX
のXXXの部分を一致させます。
// You can add more handlers here, and reference them in serverless.yml module.exports.slashCommands = (event, context, callback) => { // ここに処理を書く };
デプロイパッケージの作成
デプロイパッケージの設定をpackageに記述します。includeが明示的に追加したい項目、excludeがその逆です。基本的にはプロジェクト配下の全てがパッケージ化されますのでincludeは書かなくても問題ないかと思います。
# you can add packaging information here package: # include: exclude: - config/default_sample.json - event.json # artifact: my-service-code.zip
デプロイ
AWS上にリソースを作成します。 deploy
コマンドに -v
オプションを付けることで、CloudFormationのログをコンソールに出力することができます。ログを見ていると何が行われているか一目瞭然です。
# sls deploy -v Serverless: Creating Stack... Serverless: Checking Stack create progress... CloudFormation - CREATE_IN_PROGRESS - AWS::CloudFormation::Stack - slack-prd CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket CloudFormation - CREATE_IN_PROGRESS - AWS::S3::Bucket - ServerlessDeploymentBucket CloudFormation - CREATE_COMPLETE - AWS::S3::Bucket - ServerlessDeploymentBucket CloudFormation - CREATE_COMPLETE - AWS::CloudFormation::Stack - slack-prd Serverless: Stack create finished... Serverless: Packaging service... Serverless: Uploading CloudFormation file to S3... Serverless: Uploading service .zip file to S3... Serverless: Updating Stack... Serverless: Checking Stack update progress... CloudFormation - UPDATE_IN_PROGRESS - AWS::CloudFormation::Stack - slack-prd CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::RestApi - ApiGatewayRestApi CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::RestApi - ApiGatewayRestApi CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Role - IamRoleLambdaExecution CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceSlack CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceSlack CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceSlack CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceSlackSlashcommands CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Resource - ApiGatewayResourceSlackSlashcommands CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Resource - ApiGatewayResourceSlackSlashcommands CloudFormation - CREATE_COMPLETE - AWS::IAM::Role - IamRoleLambdaExecution CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Policy - IamPolicyLambdaExecution CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - SlashCommandsLambdaFunction CloudFormation - CREATE_IN_PROGRESS - AWS::IAM::Policy - IamPolicyLambdaExecution CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Function - SlashCommandsLambdaFunction CloudFormation - CREATE_COMPLETE - AWS::IAM::Policy - IamPolicyLambdaExecution CloudFormation - CREATE_COMPLETE - AWS::Lambda::Function - SlashCommandsLambdaFunction CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - SlashCommandsLambdaPermissionApiGateway CloudFormation - CREATE_IN_PROGRESS - AWS::Lambda::Permission - SlashCommandsLambdaPermissionApiGateway CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodSlackSlashcommandsPost CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Method - ApiGatewayMethodSlackSlashcommandsPost CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Method - ApiGatewayMethodSlackSlashcommandsPost CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1473542643677 CloudFormation - CREATE_COMPLETE - AWS::Lambda::Permission - SlashCommandsLambdaPermissionApiGateway CloudFormation - CREATE_IN_PROGRESS - AWS::ApiGateway::Deployment - ApiGatewayDeployment1473542643677 CloudFormation - CREATE_COMPLETE - AWS::ApiGateway::Deployment - ApiGatewayDeployment1473542643677 CloudFormation - UPDATE_COMPLETE_CLEANUP_IN_PROGRESS - AWS::CloudFormation::Stack - slack-prd CloudFormation - UPDATE_COMPLETE - AWS::CloudFormation::Stack - slack-prd Serverless: Stack update finished... Service Information service: slack stage: prd region: ap-northeast-1 endpoints: POST - https://xxx.execute-api.ap-northeast-1.amazonaws.com/prd/slack/slash-commands functions: slack-prd-slashCommands: arn:aws:lambda:ap-northeast-1:XXX:function:slack-prd-slashCommands
気になった点としては、デプロイ後動作は問題ないのですが、Lambdaのトリガーに設定が表示されませんでした。この機能はまだ使わないほうがいいかもしれません。
まとめ
Lambdaの開発に必要な一連の操作がほぼすべてserverlessでできました。 API Gatewayまわりの機能は怪しいのでv1.0.0がリリースされたらもう一度試してみたいと思います。フォーラムの動きがとても活発なのできっとすぐに修正されると期待しています。